import { Plugin } from 'vite';

/**
 * Vite Service代码运行时转换插件
 * 在加载Service文件时自动转换代码，无需修改源文件
 * 将ServiceBase版本转换为Api版本，适配前端调用
 */
export function viteServiceRuntimeTransform(options: {
    servicesDir?: string;      // Service目录
    targetPattern?: RegExp;    // 需要转换的文件匹配模式
} = {}): Plugin {
    const {
        servicesDir = 'srcService/services',
        targetPattern = /\.ts$/  // 转换所有TypeScript文件
    } = options;

    return {
        name: 'vite-service-runtime-transform',

        // 在加载阶段转换代码
        load(id) {
            // 只处理指定的Service文件
            if (!id.includes(servicesDir)) return null;
            if (!targetPattern.test(id)) return null;
            // 获取原始文件内容（这里模拟，实际应该从文件系统读取）
            // 由于Vite的限制，我们使用transform阶段更合适
            return null;
        },

        // 在转换阶段处理代码
        transform(code, id) {
            if (!/(\w+)Service\.ts/.test(id)) {
                return code;
            }
            try {
                // 执行代码转换
                const transformedCode = transformServiceCode(code);
                if (transformedCode !== code) {
                    return {
                        code: transformedCode,
                        map: null  // 简化处理，不生成source map
                    };
                }

                return null;
            } catch (error) {
                // 静默处理转换错误，避免影响开发体验
                console.error('Service transform error:', error);
                return null; // 返回null让Vite使用原始代码
            }
        }
    };
}

/**
 * 转换Service代码的核心函数 - 通用版本
 * 保留类名，只改变继承关系和每个方法的实现
 */
function transformServiceCode(code: string): string {
    try {
        let transformed = code;

        // 1. 先删除所有导入语句
        transformed = transformed.replace(/import\s+.*?from\s+["\'].+?["\'];\s*/g, '');

        // 2. 只添加必要的Api导入
        transformed = 'import Api from "@/api/Api";\n' + transformed;

        // 2. 替换类继承（保留类名）
        transformed = transformed.replace(
            /class (\w+) extends ServiceBase/g,
            'class $1 extends Api'
        );

        // 3. 直接移除构造函数
        transformed = transformed.replace(
            /constructor\([^)]*\)\s*\{[\s\S]*?super\([^)]*\);[\s\S]*?\}\s*/g,
            ''
        );

        // 4. 通用方法转换 - 支持async和普通箭头函数
        // 匹配方法名 = (参数) => { 内容 }; 或 方法名 = async (参数) => { 内容 };
        transformed = transformed.replace(
            /(\w+)\s*=\s*(?:async\s+)?\(([^)]*)\)\s*=>\s*\{[\s\S]*?\};\s*$/gm,
            (match, methodName, params) => {
                // 检查参数是否存在且不为空（去除空格后）
                const hasParams = params.trim() !== '';
                if (hasParams) {
                    // 保留原始参数名、类型和个数，并将这些参数作为一个整体传递给this._post
                    return `${methodName}(${params.trim()}) {\n    return this._post("${methodName}", {${params.split(',').map(param => param.trim().split(/:\s*/)[0]).join(', ')}});\n  }`;
                } else {
                    return `${methodName}() {\n    return this._post("${methodName}");\n  }`;
                }
            }
        );

        // 5. 清理可能残留的代码片段
        transformed = transformed.replace(/\s*}\s*catch\s*\([^)]*\)\s*\{[\s\S]*?\}\s*;\s*$/gm, '');
        transformed = transformed.replace(/\s*}\s*;\s*$/gm, '');

        return transformed;
    } catch (error) {
        console.error('transformServiceCode error:', error);
        return code; // 如果转换失败，返回原始代码
    }
}

export default viteServiceRuntimeTransform;